package com.mall.huohuo.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mall.huohuo.datasource.entity.TblAdvertise;
import com.mall.huohuo.datasource.mapper.TblAdvertiseMapper;
import com.mall.huohuo.result.PageResult;
import com.mall.huohuo.service.advertise.domain.AdvertiseResult;
import com.mall.huohuo.service.advertise.param.AdvertiseListParam;
import com.mall.huohuo.service.advertise.service.AdvertiseInfoService;
import com.mall.huohuo.service.enums.AdvertiseEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zycoding
 * @version AdvertiseServiceImpl.java, v 0.1 2020-08-19 23:05 zycoding
 */
@Service
@Slf4j
public class AdvertiseInfoServiceImpl implements AdvertiseInfoService {

    DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private TblAdvertiseMapper tblAdvertiseMapper;

    /**
     * 获取广告详情
     *
     * @param advertiseId 广告id
     * @return 广告详情
     */
    @Override
    public AdvertiseResult getAdvertiseDetail(Long advertiseId) {

        Assert.isTrue(advertiseId > 1, String.format("广告详情%d必须大于0", advertiseId));

        final TblAdvertise source = this.tblAdvertiseMapper.selectById(advertiseId);
        Assert.isTrue(Objects.nonNull(source), String.format("通过%d未查询来广告列表", advertiseId));

        AdvertiseResult advertiseResult = new AdvertiseResult();
        BeanUtils.copyProperties(source, advertiseResult);

        return advertiseResult;
    }

    /**
     * 列出所有的广告信息
     *
     * @param advertiseParam
     * @return 广告信息
     */
    @Override
    public PageResult<AdvertiseResult> getAdvertiseList(AdvertiseListParam advertiseParam) {
        log.info("调用广告request param:{}", JSONObject.toJSONString(advertiseParam));

        final List<AdvertiseEnum> advertisePosition = advertiseParam.getAdvertisePosition();
        final LocalDateTime now = LocalDateTime.now();
        final LambdaQueryWrapper<TblAdvertise> lambdaQuery = Wrappers.<TblAdvertise>lambdaQuery();

        // 查询指定的分组
        if (CollectionUtil.isNotEmpty(advertisePosition)) {
            final List<Integer> positionList = advertisePosition.stream().map(AdvertiseEnum::getValue).collect(Collectors.toList());
            // todo 应该写一个拦截器来处理LocalDateTime 和 localDate 和LocalTime
            lambdaQuery.in(TblAdvertise::getPosition, positionList).eq(TblAdvertise::getIsOnline, true)
                    .le(TblAdvertise::getActiveTime, now.format(DEFAULT_FORMATTER)).gt(TblAdvertise::getEndTime, now.format(DEFAULT_FORMATTER));
        }

        final Integer pageNumber = advertiseParam.getPageNumber();
        final Integer pageSize = advertiseParam.getPageSize();

        if (Objects.nonNull(pageNumber) && Objects.nonNull(pageSize)) {
            PageHelper.startPage(pageNumber, pageSize);
        }


        final List<TblAdvertise> advertises = tblAdvertiseMapper.selectList(lambdaQuery);

        // 这边会有一个转换的方法
        final PageInfo<TblAdvertise> pageInfo = new PageInfo<>(advertises);

        final PageResult<TblAdvertise> tblAdvertisePageResult = PageResult.convertPageInfo(pageInfo);
        PageResult<AdvertiseResult> pageResult = new PageResult<AdvertiseResult>();
        pageResult.setSuccess(tblAdvertisePageResult.getSuccess());
        if (!tblAdvertisePageResult.getSuccess()) {
            return pageResult;
        }
        final List<AdvertiseResult> advertiseResults = JSONObject.parseObject(JSONObject.toJSONString(advertises), new TypeReference<List<AdvertiseResult>>() {
        });
        BeanUtils.copyProperties(pageInfo, pageResult, "data");
        pageResult.setData(advertiseResults);
        return pageResult;
    }
}
